package com.vercon.commonmirror.utils;

import static android.content.Context.ACTIVITY_SERVICE;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.ActivityManager;
import android.app.Instrumentation;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.content.pm.Signature;
import android.graphics.Bitmap;
import android.graphics.Rect;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.Uri;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.os.Build;
import android.os.Environment;
import android.text.TextUtils;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.View;
import android.view.WindowManager;

import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.vercon.commonmirror.Constants;
import com.vercon.commonmirror.cache.MirrorDataStorage;

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.LineNumberReader;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
import java.net.HttpURLConnection;
import java.net.Inet4Address;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.net.URL;
import java.net.URLConnection;
import java.security.cert.Certificate;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;


/**
 * 有关APP的信息包括版本号，版本名，签名，安装路径等
 */
public class APPUtil {

    private APPUtil() {

    }

    /**
     * 获取应用包名
     *
     * @param context 上下文信息
     * @return 包名
     */
    public static String getPackageName(Context context) {
        if (context == null) {
            throw new IllegalArgumentException("Should not be null");
        }
        return context.getPackageName();
    }

    /**
     * @param context 上下文信息
     * @return 获取包信息
     */
    public static PackageInfo getPackageInfo(Context context) {
        PackageManager packageManager = context.getPackageManager();
        /** getPackageName()是当前类的包名，0代表获取版本信息 */
        try {
            return packageManager.getPackageInfo(context.getPackageName(), 0);
        } catch (PackageManager.NameNotFoundException e) {
            e.printStackTrace();
        }

        return null;
    }

    /**
     * 判断应用是否已经启动
     *
     * @param context 一个context
     * @return boolean
     */
    public static boolean isAppAlive(Context context) {
        ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
        List<ActivityManager.RunningAppProcessInfo> processInfos = activityManager.getRunningAppProcesses();
        for (int i = 0; i < processInfos.size(); i++) {
            if (processInfos.get(i).processName.equals(getPackageName(context))) {
                return true;
            }
        }
        return false;
    }

    /**
     * 获取应用版本号
     *
     * @param context
     * @return 成功返回版本号，失败返回-1
     */
    public static int getVersionCode(Context context) {
        if (getPackageInfo(context) != null) {
            return getPackageInfo(context).versionCode;
        }

        return -1;
    }

    /**
     * 获取应用版本名
     *
     * @param context
     * @return 成功返回版本名， 失败返回null
     */
    public static String getVersionName(Context context) {
        PackageInfo packageInfo = getPackageInfo(context);
        if (packageInfo != null) {
            return packageInfo.versionName;
        }
        return "";
    }

    /**
     * 判断版本名称是否有更新
     *
     * @param version     接口返回版本名称1.2.1
     * @param versionName 本地版本名称1.2
     * @return
     */
    public static boolean checkUpdate(String version, String versionName) {
        if (TextUtils.isEmpty(version) || TextUtils.isEmpty(versionName)) {
            return false;
        }
        try {
            StringBuilder s1 = new StringBuilder(version.replaceAll("\\.", "").replaceAll("v", ""));
            StringBuilder s2 = new StringBuilder(versionName.replaceAll("\\.", ""));
            int length = s1.length() - s2.length();
            if (length > 0) {
                for (int i = 0; i < length; i++) {
                    s2.append("0");
                }
            } else if (length < 0) {
                for (int i = 0; i < Math.abs(length); i++) {
                    s1.append("0");
                }
            }
            return Integer.parseInt(s1.toString()) > Integer.parseInt(s2.toString());
        } catch (Exception e) {

        }
        return false;
    }

    /**
     * 获取固件系统版本
     */
    public static String getFirmwareVersion() {
        String str = Build.DISPLAY;
        int a = str.indexOf(".");//获取这个后面的日期
        if (str.length() > a + 9) {
            str = str.substring(a + 1, a + 9);
        }
        return str;
    }
    public static String getFirmwareVersionS() {
        String str = Build.DISPLAY;
        LogUtils.e("Build.DISPLAY="+str);
        int a = str.indexOf("Q.");//获取这个后面的日期
        if (str.length() > a + 10) {
            str = str.substring(a + 2, a + 10);
        }
        return str;
    }
    /**
     * 获取固件系统版本
     */
    public static String getFirmwareUpdateVersion_k(String str) {
        LogUtils.e(str);
        int a = str.indexOf("VUI_");//获取这个后面的日期    健身镜的是FEUI_  玄关镜x1项目的是XEUI_  海外美妆镜BMEUI_  国内卫浴镜VUI_ 国外卫浴镜VEUI_
        LogUtils.e("a="+a);
        if (a >=0) {
            if (str.length() >= a + 19) {
                str = str.substring(a, a + 19);
            } else {
                str = str.substring(a);
            }
            LogUtils.e("str=" + str);
        }else {
            if (str.length() > 15) {
                str = str.substring(str.length() - 13, str.length());
            }
            LogUtils.e("str=" + str);
        }
        return str;
    }
    /**
     * 获取固件系统版本
     */
    public static String getFirmwareUpdateVersion_s(String str) {
        LogUtils.e(str);
        int a = str.indexOf("KUI_");//获取这个后面的日期
        if (str.length() >= a + 17) {
            str = str.substring(a + 4, a + 17);
        }
        return str;
    }

    /**
     * 获取APP名称
     *
     * @param context
     * @return
     */
    public static String getAppName(Context context) {
        try {
            PackageManager packageManager = context.getPackageManager();
            PackageInfo packageInfo = packageManager.getPackageInfo(context.getPackageName(), 0);
            int labelRes = packageInfo.applicationInfo.labelRes;
            return context.getResources().getString(labelRes);
        } catch (PackageManager.NameNotFoundException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 打开指定包名的APP
     *
     * @param context
     * @param packageName
     */
    public static void openOtherApp(Context context, String packageName) {
        PackageManager manager = context.getPackageManager();
        Intent launchIntentForPackage = manager.getLaunchIntentForPackage(packageName);
        if (launchIntentForPackage != null) {
            addPackageName(packageName);

            if(context.getPackageName().equals(packageName)){
                    //获取ActivityManager
                    ActivityManager activityManager = (ActivityManager) context.getSystemService(ACTIVITY_SERVICE);
                    //获得当前运行的task(任务)
                    List<ActivityManager.RunningTaskInfo> taskInfoList = activityManager.getRunningTasks(100);
                    for (ActivityManager.RunningTaskInfo taskInfo : taskInfoList) {
                        //找到本应用的 task，并将它切换到前台
                        if (taskInfo.topActivity.getPackageName().equals(context.getPackageName())) {
                            activityManager.moveTaskToFront(taskInfo.id, 0);
                            break;
                        }
                    }
                }
            }else {
                context.startActivity(launchIntentForPackage);
            }
    }

    public static void addPackageName(String packageName) {
        Constants.listApkName.add(packageName);
        Set set = new HashSet(Constants.listApkName);
        List tempList = new ArrayList(set);
        Constants.listApkName = tempList;
    }

    //删除文件
    public static void deleteFile(String path) {
        if (path == null) {
            return;
        }
        File file = new File(path);
        if (file.exists()) {
            //存在
            if (file.isFile()) {
                file.delete();
            }
        }
    }

    //删除文件夹和文件夹里面的文件
    public static void deleteDir(final String pPath) {
        File dir = new File(pPath);
        deleteDirWithFile(dir);
    }

    public static void deleteDirWithFile(File dir) {
        if (dir == null || !dir.exists() || !dir.isDirectory())
            return;
        for (File file : Objects.requireNonNull(dir.listFiles())) {
            if (file.isFile())
                file.delete(); // 删除所有文件
            else if (file.isDirectory())
                deleteDirWithFile(file); // 递规的方式删除文件夹
        }
        dir.delete();// 删除目录本身
    }

    /**
     * 判断当前ＡＰＰ处于前台还是后台；
     * 需添加<uses-permission android:name="android.permission.GET_TASKS"/>
     * 并且必须是系统应用，该方法才有效
     *
     * @param context
     * @return
     */
    public static boolean isApplicationBackground(final Context context) {
        ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
        @SuppressWarnings("deprecation")
        List<ActivityManager.RunningTaskInfo> tasks = am.getRunningTasks(1);
        if (tasks != null) {
            ComponentName topActivity = tasks.get(0).topActivity;
            return !topActivity.getPackageName().equals(context.getPackageName());
        }
        return false;
    }


    /**
     * 安装APK
     *
     * @param context
     * @param apkPath 安装包的路径
     */
    public static void installApk(Context context, Uri apkPath) {
        Intent intent = new Intent();
        intent.setAction(Intent.ACTION_VIEW);
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        intent.setDataAndType(apkPath, "application/vnd.android.package-archive");
        context.startActivity(intent);
    }

    /**
     * 卸载APP
     *
     * @param context
     * @param packageName 包名
     */
    public static void uninstallAPK(Context context, String packageName) {
        Uri packageURI = Uri.parse("package:" + packageName);
        Intent uninstallIntent = new Intent(Intent.ACTION_DELETE, packageURI);
        context.startActivity(uninstallIntent);
    }

    /**
     * 获取已安装应用的签名
     *
     * @param context
     * @return
     */
    public static String getInstalledApkSign(Context context) {
        PackageInfo packageInfo;
        try {
            PackageManager packageManager = context.getPackageManager();
            packageInfo = packageManager.getPackageInfo(context.getPackageName(), PackageManager.GET_SIGNATURES);

            return packageInfo.signatures[0].toCharsString();
        } catch (PackageManager.NameNotFoundException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 获取已安装应用 非系统的
     *
     * @param context
     * toolConfig 1 添加商店 2 添加浏览器 空，不添加
     */
    public static List<PackageInfo> installedAppListIsNotSystem(Context context, ArrayList<Integer> toolConfig) {

        List<PackageInfo> result = new ArrayList<>();
        try {
            PackageManager pm = context.getPackageManager();
            // Return a List of all packages that are installed on the device.
            List<PackageInfo> packages = pm.getInstalledPackages(0);
            for (PackageInfo packageInfo : packages) {
                // 判断系统/非系统应用
//            LogUtils.e("installedAppListIsNotSystem", "应用名：" + packageInfo.applicationInfo.loadLabel(pm));
//            LogUtils.i("installedAppListIsNotSystem", "包名：" + packageInfo.applicationInfo.packageName);
                //过滤系统应用
                if ((packageInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
                    if (getPackageName(context).equals(packageInfo.applicationInfo.packageName)) {
                        //过滤自身包名
                        continue;
                    }
                    if (Constants.testingtoolsPackeName.equals(packageInfo.applicationInfo.packageName)) {
                        //过滤质检工具
                        continue;
                    }
                    LogUtils.i("GGNotSystem", "应用名：" + packageInfo.applicationInfo.loadLabel(pm)
                            + " 包名：" + packageInfo.applicationInfo.packageName);

                    result.add(packageInfo);
                    //获取图标方法 外面获取，会卡顿
//                packageInfo.applicationInfo.loadIcon(pm);
                } else {
//                if (!TextUtils.isEmpty(toolConfig)) {
//                    if (toolConfig.equals("1") && packageInfo.applicationInfo.packageName.equals("com.android.vending")) {
//                        result.add(packageInfo);
//                        LogUtils.i("GGNotSystem", "应用名：" + packageInfo.applicationInfo.loadLabel(pm)
//                                + " 包名：" + packageInfo.applicationInfo.packageName);
//                    } else if (toolConfig.equals("2") && packageInfo.applicationInfo.packageName.equals("com.android.chrome")) {
//                        result.add(packageInfo);
//                        LogUtils.i("GGNotSystem", "应用名：" + packageInfo.applicationInfo.loadLabel(pm)
//                                + " 包名：" + packageInfo.applicationInfo.packageName);
//                    }
//                }

                    if (toolConfig != null) {
                        for (int i = 0; i < toolConfig.size(); i++) {
                            if (toolConfig.get(i) == 1 && packageInfo.applicationInfo.packageName.equals("com.android.vending")) {
                                result.add(packageInfo);
                            } else if (toolConfig.get(i) == 2 && packageInfo.applicationInfo.packageName.equals("com.android.chrome")) {
                                result.add(packageInfo);
                            }
                        }
                    }
                }
            }
        }catch (Exception e){}

        return result;
    }

    /**
     * 获取当前应用的 源Apk路径
     *
     * @param context
     * @return
     */
    public static String getOldApkSrcPath(Context context) {

        try {
            PackageManager packageManager = context.getPackageManager();
            ApplicationInfo applicationInfo = packageManager.getApplicationInfo(context.getPackageName(), 0);

            return applicationInfo.sourceDir;
        } catch (PackageManager.NameNotFoundException e) {
            e.printStackTrace();
        }

        return null;
    }

    /**
     * 获取未安装APK的签名
     *
     * @param file
     * @return
     * @throws IOException
     */
    public static List<String> getUninstallApkSignatures(File file) {
        List<String> signatures = new ArrayList<String>();
        try {
            JarFile jarFile = new JarFile(file);
            JarEntry je = jarFile.getJarEntry("AndroidManifest.xml");
            byte[] readBuffer = new byte[8192];
            Certificate[] certs = loadCertificates(jarFile, je, readBuffer);
            if (certs != null) {
                for (Certificate c : certs) {
                    String sig = toCharsString(c.getEncoded());
                    signatures.add(sig);
                }
            }
        } catch (Exception ex) {
        }
        return signatures;
    }

    /**
     * 加载签名
     *
     * @param jarFile
     * @param je
     * @param readBuffer
     * @return
     */
    private static Certificate[] loadCertificates(JarFile jarFile, JarEntry je, byte[] readBuffer) {
        try {
            InputStream is = jarFile.getInputStream(je);
            while (is.read(readBuffer, 0, readBuffer.length) != -1) {
            }
            is.close();
            return je != null ? je.getCertificates() : null;
        } catch (IOException e) {
        }
        return null;
    }

    /**
     * 将签名转成转成可见字符串
     *
     * @param sigBytes
     * @return
     */
    private static String toCharsString(byte[] sigBytes) {
        byte[] sig = sigBytes;
        final int N = sig.length;
        final int N2 = N * 2;
        char[] text = new char[N2];
        for (int j = 0; j < N; j++) {
            byte v = sig[j];
            int d = (v >> 4) & 0xf;
            text[j * 2] = (char) (d >= 10 ? ('a' + d - 10) : ('0' + d));
            d = v & 0xf;
            text[j * 2 + 1] = (char) (d >= 10 ? ('a' + d - 10) : ('0' + d));
        }
        return new String(text);
    }

    /**
     * 获取未安装APK的签名, 由于市面上的Android系统版本各一，不推荐使用这种方法获取应用签名
     *
     * @param apkPath
     * @return
     */
    public static String getUninstallAPKSignatures(String apkPath) {
        //参数列表类型
        Class[] typeArgs = new Class[1];
        //参数列表值
        Object[] valueArgs = new Object[1];
        try {
            //2.这是一个Package 解释器, 是隐藏的，获取PackageParser的类
            Class pkgParserCls = Class.forName("android.content.pm.PackageParser");

            //2.创建PackageParser的实例
            typeArgs[0] = String.class;
            Constructor pkgParserCt = pkgParserCls.getConstructor(typeArgs);
            valueArgs[0] = apkPath;
            Object pkgParser = pkgParserCt.newInstance(valueArgs);

            //3.获取PackageParser的类的  parsePackage方法；PackageParser.Package mPkgInfo = packageParser.parsePackage(new File(apkPath), apkPath, metrics, 0);   
            typeArgs = new Class[4];
            typeArgs[0] = File.class;
            typeArgs[1] = String.class;
            typeArgs[2] = DisplayMetrics.class;
            typeArgs[3] = int.class;
            Method pkgParser_parsePackageMtd = pkgParserCls.getDeclaredMethod("parsePackage", typeArgs);

            //4.执行parsePackage方法
            valueArgs = new Object[4];
            valueArgs[0] = new File(apkPath);
            valueArgs[1] = apkPath;
            DisplayMetrics metrics = new DisplayMetrics();
            metrics.setToDefaults();
            valueArgs[2] = metrics;
            valueArgs[3] = PackageManager.GET_SIGNATURES;
            Object pkgParserPkg = pkgParser_parsePackageMtd.invoke(pkgParser, valueArgs);

            //5.获取PackageParser类的collectCertificates方法
            typeArgs = new Class[2];
            typeArgs[0] = pkgParserPkg.getClass();
            typeArgs[1] = int.class;
            Method pkgParser_collectCertificatesMtd = pkgParserCls.getDeclaredMethod("collectCertificates", typeArgs);

            //6.执行collectCertificates方法
            valueArgs = new Object[2];
            valueArgs[0] = pkgParserPkg;
            valueArgs[1] = PackageManager.GET_SIGNATURES;
            pkgParser_collectCertificatesMtd.invoke(pkgParser, valueArgs);

            //7.获取PackageParser.Package的类的mSignatures属性
            Field packageInfoFld = pkgParserPkg.getClass().getDeclaredField("mSignatures");

            //8.获取PackageParser.Package的类的mSignatures属性的值
            Signature[] info = (Signature[]) packageInfoFld.get(pkgParserPkg);
            return info[0].toCharsString();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 获取手机IP地址
     *
     * @param context
     * @return 有线网络获取不到，推荐下面获取方法
     */
    public static String getIPAddress(Context context) {
        NetworkInfo info = ((ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE)).getActiveNetworkInfo();
        if (info != null && info.isConnected()) {
            if (info.getType() == ConnectivityManager.TYPE_MOBILE) {//当前使用2G/3G/4G网络
                try {
                    //Enumeration<NetworkInterface> en=NetworkInterface.getNetworkInterfaces();
                    for (Enumeration<NetworkInterface> en = NetworkInterface.getNetworkInterfaces(); en.hasMoreElements(); ) {
                        NetworkInterface intf = en.nextElement();
                        for (Enumeration<InetAddress> enumIpAddr = intf.getInetAddresses(); enumIpAddr.hasMoreElements(); ) {
                            InetAddress inetAddress = enumIpAddr.nextElement();
                            if (!inetAddress.isLoopbackAddress() && inetAddress instanceof Inet4Address) {
                                return inetAddress.getHostAddress();
                            }
                        }
                    }
                } catch (SocketException e) {
                    e.printStackTrace();
                }

            } else if (info.getType() == ConnectivityManager.TYPE_WIFI) {//当前使用无线网络
                WifiManager wifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
                WifiInfo wifiInfo = wifiManager.getConnectionInfo();
                String ipAddress = intIP2StringIP(wifiInfo.getIpAddress());//得到IPV4地址
                return ipAddress;
            }
        } else {
            //当前无网络连接,请在设置中打开网络
        }
        return "";
    }

    /**
     * 有线无线网络IP地址都能获取
     *
     * @return IP地址
     */

    public static String getIp() {
        try {
            for (Enumeration<NetworkInterface> en = NetworkInterface
                    .getNetworkInterfaces(); en.hasMoreElements(); ) {
                NetworkInterface intf = en.nextElement();
                if (intf.getName().equalsIgnoreCase("eth0") || intf.getName().equalsIgnoreCase("wlan0")) {
                    for (Enumeration<InetAddress> enumIpAddr = intf.getInetAddresses(); enumIpAddr.hasMoreElements(); ) {
                        InetAddress inetAddress = enumIpAddr.nextElement();
                        if (!inetAddress.isLoopbackAddress()) {
                            String ipaddress = inetAddress.getHostAddress();
                            if (!ipaddress.contains("::") && !ipaddress.contains(":") && ipaddress.contains(".")) {//ipV6的地址
                                return ipaddress;
                            } else {
                                return getIpAddressString();
                            }
                        }
                    }
                } else {
                    continue;
                }
            }
        } catch (SocketException e) {
            e.printStackTrace();
        }
        return null;
    }

    private static String getIpAddressString() {
        try {
            for (Enumeration<NetworkInterface> enNetI = NetworkInterface
                    .getNetworkInterfaces(); enNetI.hasMoreElements(); ) {
                NetworkInterface netI = enNetI.nextElement();
                for (Enumeration<InetAddress> enumIpAddr = netI
                        .getInetAddresses(); enumIpAddr.hasMoreElements(); ) {
                    InetAddress inetAddress = enumIpAddr.nextElement();
                    if (inetAddress instanceof Inet4Address && !inetAddress.isLoopbackAddress()) {
                        return inetAddress.getHostAddress();
                    }
                }
            }
        } catch (SocketException e) {
            e.printStackTrace();
        }
        return "0.0.0.0";
    }

    /**
     * 将得到的int类型的IP转换为String类型
     *
     * @param ip
     * @return
     */
    public static String intIP2StringIP(int ip) {
        return (ip & 0xFF) + "." +
                ((ip >> 8) & 0xFF) + "." +
                ((ip >> 16) & 0xFF) + "." +
                (ip >> 24 & 0xFF);
    }

    /**
     * 截屏
     *
     * @param activity
     * @return
     */
    public static Bitmap takeScreenShot(Activity activity) {
        // View是你需要截图的View
        View view = activity.getWindow().getDecorView();
        view.setDrawingCacheEnabled(true);
        view.buildDrawingCache();
        Bitmap b1 = null;
        try {
            b1 = view.getDrawingCache();
        } catch (OutOfMemoryError e) {
            // TODO: handle exception
        }

        // 获取状态栏高度
        Rect frame = new Rect();
        activity.getWindow().getDecorView().getWindowVisibleDisplayFrame(frame);
        int statusBarHeight = frame.top;
        System.out.println(statusBarHeight);
        // 获取屏幕长和高
        int width = activity.getWindowManager().getDefaultDisplay().getWidth();
        int height = activity.getWindowManager().getDefaultDisplay().getHeight();
        // 去掉标题栏
        // Bitmap b = Bitmap.createBitmap(b1, 0, 25, 320, 455);
        Bitmap b = Bitmap.createBitmap(b1, 0, 0, b1.getWidth(), b1.getHeight());
        view.destroyDrawingCache();
        return b;
    }

    /**
     * 获取设备CPUID
     */
    public static String getCPUSerial() {
        String str;
        String strCPU;
        String cpuAddress = "0000000000000000";
        try {
            //读取CPU信息
            Process pp = Runtime.getRuntime().exec("cat /proc/cpuinfo");
            InputStreamReader ir = new InputStreamReader(pp.getInputStream());
            LineNumberReader input = new LineNumberReader(ir);
            //查找CPU序列号
            for (int i = 1; i < 100; i++) {
                str = input.readLine();
                if (str != null) {
                    //查找到序列号所在行
                    Log.e("getCPUID", str);

                    if (str.contains("Serial")) {
                        //提取序列号
                        strCPU = str.substring(str.indexOf(":") + 1);
                        //去空格
                        cpuAddress = strCPU.trim();
                        break;
                    }
                } else {
                    //文件结尾
                    break;
                }
            }
        } catch (Exception ex) {
            //赋予默认值
            ex.printStackTrace();
            Log.e("getCPUSerial", ex.getMessage());
        }
        return cpuAddress;
    }


    /**
     * 获取手机序列号
     *
     * @return 手机序列号
     */
    public static String getSerialNumber() {
        String serial = "";
        try {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {//9.0+
                serial = Build.getSerial();
            } else if (Build.VERSION.SDK_INT > Build.VERSION_CODES.N) {//8.0+
                serial = Build.SERIAL;
            } else {//8.0-
                Class<?> c = Class.forName("android.os.SystemProperties");
                Method get = c.getMethod("get", String.class);
                serial = (String) get.invoke(c, "ro.serialno");
            }
        } catch (Exception e) {
            e.printStackTrace();
            Log.d("APPUtil", e.getMessage());

        }
        return serial;
    }

    /**
     * 反射获取
     *
     * @param key          键
     * @param defaultValue 默认值
     * @return
     */
    public static String getSystem(String key, String defaultValue) {
        //persist.product.version=0/1 获取桌面应用状态
        try {
            Class<?> c = Class.forName("android.os.SystemProperties");
            Method get = c.getMethod("get", String.class, String.class);
            return (String) get.invoke(c, key, defaultValue);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "";
    }

    /**
     * 反射设置
     *
     * @param key   键
     * @param value 设置值
     */
    public static void setSystem(String key, String value) {
        //persist.product.version=0/1  设置桌面应用状态
        try {
            Class<?> c = Class.forName("android.os.SystemProperties");
            Method set = c.getMethod("set", String.class, String.class);
            set.invoke(c, key, value);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 关闭所有后台进程APP，验证有效
     */
    public static void clearAllApp(Context context) {
        Runnable runnable = () -> {
            ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
            List<ActivityManager.RunningAppProcessInfo> list = am.getRunningAppProcesses();
            if (list != null) {
                for (int i = 0; i < list.size(); i++) {
                    ActivityManager.RunningAppProcessInfo appProcessInfo = list.get(i);
                    String[] pkgList = appProcessInfo.pkgList;
                    if (appProcessInfo.importance > ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND) {
                        // 清理后台进程
                        for (String pkg : pkgList) {
                            if (pkg.matches("com.android.*") && !pkg.contains("launcher") && !pkg.contains("settings")) {
                                LogUtils.d("not clean is system android pid pkg= " + pkg);
                            } else {
                                LogUtils.d("auto clean apk pkg= " + pkg);
                                if (!APPUtil.getPackageName(context).equals(pkg)) {
                                    closeApp(context, pkg);
                                }
                            }
                        }
                    }
                }
            }
        };
        runnable.run();
    }

    public static void closeApp(Context context, String packageName) {

        if (!TextUtils.isEmpty(packageName)) {
            ActivityManager mActivityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
            Method method;
            try {
                method = Class.forName("android.app.ActivityManager").getMethod("forceStopPackage", String.class);
                try {
                    method.invoke(mActivityManager, packageName);  //packageName是需要强制停止的应用程序包名
                    MirrorDataStorage.instance().storeString(Constants.current_application, "");
                    LogUtils.e("关闭app成功");
                } catch (IllegalAccessException | InvocationTargetException e) {
                    LogUtils.e("关闭app失败");
                    e.printStackTrace();
                }

            } catch (NoSuchMethodException | ClassNotFoundException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 不够30位补0，正式版是30位
     * 加密逻辑：设备码位数有30位，将设备码分为6组，a组4位、b组5位、c组6位、d组4位、e组5位、f组6位，顺序变换为dabefc
     * 如：2f447e5a4674b64a8b4fb4ee12bf81拆分后，2f44(a)7e5a4(b
     * )674b64(c)a8b4(d)fb4ee(e)12bf81(f)顺序变换→a8b4(d) 2f44(a)7e5a4(b
     * )fb4ee(e)12bf81(f)674b64(c)= a8b42f447e5a4fb4ee12bf81674b64
     *
     * @return
     */
//    public static String getSerialEncryptionNum() {
//        //获取加密的手机序列号
//        String serial = getSerialNumber();
//        StringBuilder num = new StringBuilder();
//        if (serial.length() < 30) {
//            for (int i = 0; i < 30 - serial.length(); i++) {
//                num.append("0");
//            }
//            serial = serial + num;
//
//        }
//        LogUtils.i("getSerialEncryptionNum", "变化前：" + serial);
//
//        String a, b, c, d, e, f;
//        a = serial.substring(0, 4);
//        b = serial.substring(4, 9);
//        c = serial.substring(9, 15);
//        d = serial.substring(15, 19);
//        e = serial.substring(19, 24);
//        f = serial.substring(24);
//        LogUtils.i("getSerialEncryptionNum", "变化中：" + serial + "  " + a + "  " + b + "  " + c + "  " + d + "  " + e + "  " + f);
//        serial = d + a + b + e + f + c;
//        LogUtils.i("getSerialEncryptionNum", "变化后：" + serial);
//
//        return serial;
//    }
    public static String getSerialEncryptionNum() {
        //获取加密的手机序列号
        String serial = getSerialNumber();
        LogUtils.i("APPUtil", "变化前：" + serial);
        if (serial.length() > 12) {
            serial = serial.substring(0, 12);
        } else if (serial.length() < 12) {
            return serial;
        }
        LogUtils.i("APPUtil", "变化前截断：" + serial);
        String[] num = new String[12];
        for (int i = 0; i < serial.length(); i++) {
            num[i] = serial.substring(i, i + 1);
        }
        serial = num[0] + num[11] + num[1] + num[10] + num[2] + num[9] + num[3] + num[8] + num[4] + num[7] + num[5] + num[6];

        LogUtils.i("getSerialEncryptionNum", "变化后：" + serial);

        return serial;
    }

    /**
     * 启用第三方应用图标
     * 需设置为系统应用
     *
     * @param context
     * @param packageName
     */
    public static void startApp(Context context, String packageName) {
        PackageManager pm = context.getPackageManager();
        pm.setApplicationEnabledSetting(packageName, PackageManager.COMPONENT_ENABLED_STATE_DEFAULT, 0);
    }

    /**
     * 禁用第三方图标
     * 需设置为系统应用
     *
     * @param context
     * @param packageName
     */
    public static void stopApp(Context context, String packageName) {
        PackageManager pm = context.getPackageManager();
        pm.setApplicationEnabledSetting(packageName, PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER, 0);
    }

    public static void sendKeyEvent(int KeyCode) {
        ThreadUtil.getInstance().getExecutorService().execute(() -> {
            //不可在主线程中调用,所以这里使用线程发送
            try {
                Instrumentation inst = new Instrumentation();
                inst.sendKeyDownUpSync(KeyCode);
            } catch (Exception e) {
                e.printStackTrace();
            }
        });
    }

    /**
     * 判断本地是否已经安装好了指定的应用程序包
     *
     * @param packageNameTarget ：待判断的 App 包名
     * @return 已安装时返回 true,不存在时返回 false
     */
    public static boolean appIsExist(Context context, String packageNameTarget) {
        if (packageNameTarget == null || packageNameTarget.isEmpty()) {
            return false;
        }
        PackageManager packageManager = context.getPackageManager();
        List<PackageInfo> packageInfoList = packageManager.getInstalledPackages(PackageManager.MATCH_UNINSTALLED_PACKAGES);
        for (PackageInfo packageInfo : packageInfoList) {
            if (packageInfo.packageName.equals(packageNameTarget)) {
                return true;
            }
        }
        return false;
    }

    public static Intent getAppOpenIntentByPackageName(Context context, String packageName) {
        String mainAct = null;
        PackageManager pkgMag = context.getPackageManager();
        Intent intent = new Intent(Intent.ACTION_MAIN);
        intent.addCategory(Intent.CATEGORY_LAUNCHER);
        intent.setFlags(Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED | Intent.FLAG_ACTIVITY_NEW_TASK);

        @SuppressLint({"WrongConstant", "QueryPermissionsNeeded"}) List<ResolveInfo> list = pkgMag.queryIntentActivities(intent,
                PackageManager.GET_ACTIVITIES);
        for (int i = 0; i < list.size(); i++) {
            ResolveInfo info = list.get(i);
            if (info.activityInfo.packageName.equals(packageName)) {
                mainAct = info.activityInfo.name;
                break;
            }
        }
        if (TextUtils.isEmpty(mainAct)) {
            return null;
        }
        intent.setComponent(new ComponentName(packageName, mainAct));
        return intent;
    }

    public static boolean isAndroid_11(Context context){

        DisplayMetrics metric = new DisplayMetrics();
        WindowManager mWindowManager  = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
        mWindowManager.getDefaultDisplay().getMetrics(metric);

        int width=metric.widthPixels; // 宽度（PX）
        int height=metric.heightPixels; // 高度（PX）

        float density=metric.density; // 密度（0.75 / 1.0 / 1.5）
        int densityDpi=metric.densityDpi; // 密度DPI（120 / 160 / 240）

        //屏幕宽度算法:屏幕宽度（像素）/屏幕密度
        int screenWidth = (int) (width/density);//屏幕宽度(dp)
        int screenHeight = (int)(height/density);//屏幕高度(dp)

        String a = "宽度:" + width + " 高度:" + height + " 密度:" + density + " 密度DPI:" + densityDpi
                + "\r\n屏幕dp宽度：" + screenWidth + " 屏幕dp高度：" + screenHeight;
        LogUtils.e(a);
        if (screenWidth > 1150 && screenWidth < 1300){//这个最小宽度代表是K系列的
            return true;
        }else if (screenWidth == 1920){//这个宽度代表是S系列
            return false;
        }
        return false;
    }
}
